/**
 * HTML5上传插件
 * @site https://git.oschina.net/blackfox/ajaxUpload
 * @author yangjian<yangjian102621@gmail.com>
 * @version 1.0.1
 */
(function ($) {

	//判断浏览器是否支持html5
	if (typeof FormData == "undefined")
		throw new Error("您当前的浏览器不支持HTML5,请先升级浏览器才能使用该上传插件!");

	//image crop
	$.fn.imageCrop = function (__width, __height) {
		$(this).on("load", function () {

			var width, height, left, top;
			var orgRate = this.width / this.height;
			var cropRate = __width / __height;
			if (orgRate >= cropRate) {
				height = __height;
				width = __width * orgRate;
				top = 0;
				left = (width - __width) / 2;
			} else {
				width = __width;
				height = __height / orgRate;
				left = 0;
				//top = (height - __height)/2;
				top = 0;
			}
			$(this).css({
				"position": "absolute",
				top: -top + "px",
				left: -left + "px",
				width: width + "px",
				height: height + "px"
			});
		});
	}

	//make element draggable
	$.fn.draggable = function (options) {
		var defaults = {
			handler: null
		}
		options = $.extend(defaults, options);
		var __self = this;
		$(options.handler).mousedown(function (e) {
			var offsetLeft = e.pageX - $(__self).position().left;
			var offsetTop = e.pageY - $(__self).position().top;
			$(document).mousemove(function (e) {
				//清除拖动鼠标的时候选择文本
				window.getSelection ? window.getSelection().removeAllRanges() : document.selection.empty();
				$(__self).css({
					'top': e.pageY - offsetTop + 'px',
					'left': e.pageX - offsetLeft + 'px'
				});
			});

		}).mouseup(function () {
			$(document).unbind('mousemove');
		});

	}

	if (Array.prototype.remove == undefined) {
		Array.prototype.remove = function (item) {
			for (var i = 0; i < this.length; i++) {
				if (this[i] == item) {
					this.splice(i, 1);
					break;
				}
			}
		}
	}
	if (Array.prototype.uinque == undefined) {
		Array.prototype.uinque = function () {
			var result = [], hash = {};
			for (var i = 0, item; (item = this[i]) != null; i++) {
				if (!hash[item]) {
					result.push(item);
					hash[item] = true;
				}
			}
			return result;
		}
	}

	window.BUpload = function (options) {

		options = $.extend({
			src: "src",
			upload_url: null,
			data_type: "json",
			top: 20,
			fileType: "image", //文件类型，默认是图片，可选flash,media,file
			max_filesize: 4096,    //unit:KB
			max_filenum: 20,
			ext_allow: "jpg|png|gif|jpeg",
			ext_refuse: "exe|txt",
			extra_params: {},
			errorHandler: function (messsage, type) {
				alert(messsage);
			},
			callback: function (data) {
				console.log(data);
			}
		}, options);

		//错误代码和提示消息
		var codeMessageMap = {
			'0': '文件上传成功',
			'1': '文件上传失败',
			'3': '文件大小超出限制',
			'4': '非法文件名后缀'
		};

		var mimeType = {
			"3gpp": "audio/3gpp, video/3gpp",
			"ac3": "audio/ac3",
			"asf": "allpication/vnd.ms-asf",
			"au": "audio/basic",
			"css": "text/css",
			"csv": "text/csv",
			"doc": "application/msword",
			"dot": "application/msword",
			"dtd": "application/xml-dtd",
			"dwg": "image/vnd.dwg",
			"dxf": "image/vnd.dxf",
			"gif": "image/gif",
			"htm": "text/html",
			"html": "text/html",
			"jp2": "image/jp2",
			"jpe": "image/jpeg",
			"jpeg": "image/jpeg",
			"jpg": "image/jpeg",
			"js": "text/javascript, application/javascript",
			"json": "application/json",
			"mp2": "audio/mpeg, video/mpeg",
			"mp3": "audio/mpeg",
			"mp4": "audio/mp4, video/mp4",
			"mpeg": "video/mpeg",
			"mpg": "video/mpeg",
			"mpp": "application/vnd.ms-project",
			"ogg": "application/ogg, audio/ogg",
			"pdf": "application/pdf",
			"png": "image/png",
			"pot": "application/vnd.ms-powerpoint",
			"pps": "application/vnd.ms-powerpoint",
			"ppt": "application/vnd.ms-powerpoint",
			"rtf": "application/rtf, text/rtf",
			"svf": "image/vnd.svf",
			"tif": "image/tiff",
			"tiff": "image/tiff",
			"txt": "text/plain",
			"wdb": "application/vnd.ms-works",
			"wps": "application/vnd.ms-works",
			"xhtml": "application/xhtml+xml",
			"xlc": "application/vnd.ms-excel",
			"xlm": "application/vnd.ms-excel",
			"xls": "application/vnd.ms-excel",
			"xlt": "application/vnd.ms-excel",
			"xlw": "application/vnd.ms-excel",
			"xml": "text/xml, application/xml",
			"zip": "aplication/zip",
			"xlsx": "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"
		}

		var o = {};
		o.dialog = null;
		o.todoList = new Array(); //the file queue to be uploaded
		o.uploadSuccessNum = 0; //已经上传成功的图片数量
		o.selectedList = new Array(); //the file queue upload successfully
		o.addedFileNumber = 0; //the numbers of files that has added
		o.totalFilesize = 0; //total file size
		o.uploadLock = false; //upload thread lock
		var dialogSCode = Math.ceil(Math.random() * 1000000000000); //对话框的令牌，如果创建多个BUpload上传对象用来保持唯一性

		//close the dialog
		o.close = function () {
			o.dialog.remove();
			if (typeof options.close == 'function') {
				options.close();
			}
		}

		//create dialog
		function createDialog() {

			var builder = new StringBuilder();
			builder.append('<div class="uedbody ke-animated"><div class="ued_title">');
			builder.append('<div class="uedbar"><span>' + options.lang.title + '</span></div><div class="close_btn icon"' +
				' title="' + options.lang.closeText + '"></div>');
			builder.append('</div><div class="wrapper"><div id="wra_head" class="wra_head"><span class="tab' +
				' tab-upload focus" tab="upload-panel">' + options.lang.localUpload + '</span>');
			builder.append('</div><div class="wra_body"><div class="tab-panel upload-panel"><div class="wra_pla"><div class="upload-image-placeholder">');
			builder.append('<div class="btn btn-primary image-select">' + options.lang.selectFile + '</div><input type="file" name="' + options.src + '" class="webuploader-element-invisible"' +
				' multiple="multiple" accept="' + getAccept() + '">');
			builder.append('</div></div><div class="image-list-box" style="display: none;"><div class="wra_bar"><div class="info fl"></div>');
			builder.append('<div class="fr"><span class="btn btn-default btn-continue-add">' + options.lang.continueAdd + '</span><span class="btn btn-primary btn-start-upload">' + options.lang.startUpload + '</span></div></div>');
			builder.append('<ul class="filelist"></ul></div></div>');

			builder.append('<div class="loading-icon"></div></div><!-- end of wrapper --></div><div class="wra-btn-group"><span class="btn btn-primary btn-confirm">' + options.lang.confirmBtnText + '</span>');
			builder.append('<span class="btn btn-default btn-cancel">' + options.lang.cancelBtnText + '</span></div></div>');

			o.dialog = $(builder.toString());
			$("body").append(o.dialog);
			if (options.top == 0) {
				options.top = ($(window).height() - o.dialog.height()) / 2;
			}
			o.dialog.css({
				left: ($(window).width() - o.dialog.width()) / 2 + "px",
				top: options.top + "px"
			});
			//给对话框添加拖拽事件
			o.dialog.draggable({ handler: o.dialog.find(".ued_title") })

		}

		//绑定元素事件
		function bindEvent() {

			//选项卡事件
			G(".tab").on("click", function () {
				var tab = $(this).attr("tab");
				G(".tab-panel").hide();
				G("." + tab).show();
				G(".tab").removeClass("focus");
				$(this).addClass("focus");
			});

			//关闭对话框
			G(".close_btn").on("click", function () {
				o.close();
			});

			//选择文件事件
			G(".webuploader-element-invisible").on("change", function () {
				addFiles(this);
			});

			//弹出上传文件选择框
			G(".image-select").on("click", function () {
				G(".webuploader-element-invisible").trigger("click");
			});
			G(".btn-continue-add").on("click", function () {
				G(".webuploader-element-invisible").trigger("click");
			});

			//开始上传按钮事件
			G(".btn-start-upload").on("click", function () {
				if (o.uploadLock) return;

				if (o.todoList.length == 0) {
					options.errorHandler(options.lang.noFileAdded, "error");
					return false;
				}
				$(this).addClass("disabled").text(options.lang.uploading);
				uploadFile(o.todoList.shift());
			});

			//点击确认|取消按钮事件
			G(".btn-confirm").on("click", function () {
				if (o.todoList.length > 0) {
					options.errorHandler(options.lang.fileNotUpload, "error");
					return false;
				}
				if (o.selectedList.length == 0) {
					options.errorHandler(options.lang.noFileSelected, "error");
					return false;
				}
				options.callback(o.selectedList);
				o.close();

			});
			G(".btn-cancel").on("click", function () {
				o.close();
			});
		}

		//add file to upload list
		function addFiles(input) {

			var files = input.files;
			var totalFileNum = o.todoList.length + o.uploadSuccessNum + files.length; //本次上传文件总数
			for (var i = o.addedFileNumber; i < o.addedFileNumber + files.length; i++) {

				if (totalFileNum > options.max_filenum) {
					options.errorHandler(KindEditor.tmpl(options.lang.uploadLimit, { uploadLimit: options.max_filenum }), "error");
					return;
				}
				var builder = new StringBuilder();
				var tempFile = files[i - o.addedFileNumber];
				builder.append('<li id="img-comtainer-' + dialogSCode + i + '"><div class="imgWrap">');

				//如果上传的不是图片，则通过判断文件后缀来显示不同的图标
				var extension = getFileExt(tempFile.name);
				if (extension == '') extension = "default";
				extension = extension.toLowerCase();
				if ("jpg|jpeg|gif|png|bmp".indexOf(extension) == -1) {
					builder.append('<span class="icon-placeholder icon-default icon-' + extension + '"></span>');
				} else {
					builder.append('<img src="' + window.URL.createObjectURL(tempFile) + '" border="0" />');
				}

				builder.append('</div><div class="file-opt-box clearfix"><span class="remove" index="' + i + '">' + options.lang.remove + '</span><span class="rotateRight">' + options.lang.rotateRight + '</span>');
				builder.append('<span class="rotateLeft">' + options.lang.rotateLeft + '</span></div><div class="success"></div><div class="error"></div>');
				builder.append('<div class="progress"><span style="display: none; width: 0px;"></span></div></li>');

				var $image = $(builder.toString());
				//bind onelele event
				$image.find(".remove").on("click", function () {
					$(this).parents("li").remove(); //remove element
					//remove file from todoList
					var index = $(this).attr("index");
					for (var i = 0; i < o.todoList.length; i++) {
						if (o.todoList[i].index == index) {
							o.totalFilesize -= o.todoList[i].file.size;
							updateInfoText(o.uploadSuccessNum + o.todoList.length - 1, o.totalFilesize);
							o.todoList.splice(i, 1);
							break;
						}
					}
					if (G(".filelist li").length == 0) {
						G(".image-list-box").hide();
						G(".wra_pla").show();
					}
				});
				$image.on("mouseover", function () {
					$(this).find(".file-opt-box").show();
				}).on("mouseout", function () {
					$(this).find(".file-opt-box").hide();
				});

				G(".wra_pla").hide();
				G(".image-list-box").show();
				G(".filelist").append($image);

				o.todoList.push({ index: i, file: tempFile });
				o.totalFilesize += tempFile.size;

				//console.log(tempFile);
			}
			o.addedFileNumber += files.length;
			updateInfoText(o.uploadSuccessNum + o.todoList.length, o.totalFilesize);

			//缩放并裁剪图片
			$(".imgWrap img").imageCrop(113, 113);

		}

		/**
		 * upload file function(文件上传主函数)
		 * @param node 数据节点
		 */
		function uploadFile(node) {

			if (!fileCheckHandler(node)) {
				uploadNextFile();   //skip the file and upload the next file
				return;
			}

			// prepare XMLHttpRequest
			var xhr = new XMLHttpRequest();
			xhr.open('POST', options.upload_url);
			//upload successfully
			xhr.addEventListener('load', function (e) {

				if (options.data_type == "json") {
					//console.log(e);
					var data = $.parseJSON(e.target.responseText);
					if (data.error == "0") {
						o.selectedList.push(data);   //添加文件到上传文件列表
						o.uploadSuccessNum++;
						$("#img-comtainer-" + dialogSCode + node.index).find(".file-opt-box").remove();
						$("#img-comtainer-" + dialogSCode + node.index).find(".progress").remove();
						$("#img-comtainer-" + dialogSCode + node.index).find(".success").show();
					} else {
						__error__(codeMessageMap[data.error], node);
					}
				}

			}, false);

			// file upload complete
			xhr.addEventListener('loadend', function () {
				uploadNextFile();   //upload the next file
			}, false);

			//上传失败
			xhr.addEventListener('error', function () {
				__error__(options.lang.uploadFail, node);
			}, false);

			xhr.upload.addEventListener('progress', function (e) {
				updateProgress(e, node);
			}, false);

			// prepare FormData
			var formData = new FormData();
			formData.append(options.src, node.file);
			// add extra params
			for (var k in options.extra_params) {
				formData.append(k, options.extra_params[k]);
			}
			xhr.send(formData);

		}

		//upload next file(上传下一个文件)
		function uploadNextFile() {

			if (o.todoList.length) {
				var nextFile = o.todoList.shift();
				uploadFile(nextFile);
			} else {
				o.uploadLock = false; //release the upload lock
				G(".btn-start-upload").removeClass("disabled").text(options.lang.startUpload);
				//console.log(o.selectedList);
			}
		}

		// progress handler(文件上传进度控制)
		function updateProgress(e, node) {
			if (e.lengthComputable) {
				$("#img-comtainer-" + dialogSCode + node.index).find(".progress span").css({ "width": (e.loaded / e.total) * 100 + '%', "display": "block" });
			}
		}

		//update file info text
		function updateInfoText(filenum, filesize) {
			var text = KindEditor.tmpl(options.lang.uploadDesc, { numSelect: filenum, totalSize: formatFileSize(filesize), numLeft: (options.max_filenum - filenum) });
			G(".info").text(text);
		}

		//format file size(格式化文件大小)
		function formatFileSize(size) {

			if (size / 1048576 > 1) {
				return (size / 1048576).toFixed(2) + "MB";
			} else {
				return (size / 1024).toFixed(2) + "KB";
			}

		}

		//file check handler(文件检测处理函数)
		function fileCheckHandler(node) {

			//检查文件大小
			var maxsize = options.max_filesize * 1024;
			if (maxsize > 0 && node.file.size > maxsize) {
				__error__(KindEditor.tmpl(options.lang.sizeLimit, { sizeLimit: options.max_filesize }), node);
				return false;
			}

			//检查文件后缀名
			var ext = getFileExt(node.file.name);
			if (ext && options.ext_allow.indexOf(ext) != -1
				&& options.ext_refuse.indexOf(ext) == -1) {
				return true;
			} else {
				__error__(KindEditor.tmpl(options.lang.invalidExt, { invalidExt: ext }), node);
				return false;
			}

		}

		//获取文件后缀名
		function getFileExt(filename) {
			if (!filename) return false;
			var position = filename.lastIndexOf('.')
			if (position != -1) {
				return filename.substr(position + 1).toLowerCase();
			}
			return false;
		}

		//获取可接受的文件后缀
		function getAccept() {
			var extensions = options.ext_allow.split("|");
			var accept = [];
			$.each(extensions, function (idx, item) {
				accept.push(mimeType[item]);
			});
			if (accept.length > 1) {
				return accept.uinque().join(",");
			}
			return "*";
		}

		//显示上传错误信息
		function __error__(message, node) {
			G("#img-comtainer-" + dialogSCode + node.index).find(".error").show().text(message);
		}

		//query
		function G(query) {
			return o.dialog.find(query);
		}

		//initialize dialog
		createDialog();
		bindEvent();
		return o;
	}; //end of JUpload

	//string builder
	var StringBuilder = function () {

		var buffer = new Array();
		StringBuilder.prototype.append = function (str) {
			buffer.push(str);
		}

		StringBuilder.prototype.toString = function () {
			return buffer.join("");
		}

	}


})(jQuery);